package baiqitun.stupro.security.core.service.support;

import baiqitun.stupro.common.enums.BooleanEnum;
import baiqitun.stupro.common.util.AuthUtil;
import baiqitun.stupro.security.core.service.UserPermissionValidator;
import baiqitun.stupro.security.entity.SysPermission;
import baiqitun.stupro.security.service.SysPermissionService;
import baiqitun.stupro.security.service.SysRolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AntPathMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.List;

/**
 * @author kedaji
 */
@Service("userPermissionValidatorImpl")
public class UserPermissionValidatorImpl implements UserPermissionValidator {

    @Value("${server.servlet.context-path}")
    private String contextPath;
    @Autowired
    private SysPermissionService sysPermissionService;

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public boolean hasPermission(HttpServletRequest httpServletRequest, Authentication authentication) {
        String requestUri = httpServletRequest.getRequestURI().replace(contextPath, "");
        String method = httpServletRequest.getMethod();
        Collection<? extends GrantedAuthority> authorities = AuthUtil.getAuthorities(authentication);
        SysPermission permission = sysPermissionService.getPermission(requestUri, method);
        // 许可不可用
        if (permission != null){
            if (BooleanEnum.FALSE.getValue().equals(permission.getEnabled())){
                return false;
            }
            // 查找用户当前的角色是否有权限访问permission
            for (GrantedAuthority grantedAuthority: authorities){
                String roleCode = grantedAuthority.getAuthority();
                if (sysPermissionService.hasRelationByRoleCode(roleCode, permission.getId())){
                    return true;
                }
            }
        } else {
            // 当前url可能是符合ant风格的url
            for (GrantedAuthority grantedAuthority: authorities){
                String roleCode = grantedAuthority.getAuthority();
                List<SysPermission> permissions = sysPermissionService.listRootPermissionByRoleCode(roleCode, null);
                AntPathMatcher uriMatcher = new AntPathMatcher();
                for (SysPermission tmpPermission: permissions){
                    if (uriMatcher.match(tmpPermission.getUri(), requestUri)
                            && tmpPermission.getMethod().toUpperCase().equals(method)){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
